home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / emulator / bsvc-1.000 / bsvc-1 / bsvc-1.0.4 / samples / Motorola68000 / MatrixMultiply.s < prev    next >
Text File  |  1995-07-26  |  23KB  |  1,018 lines

  1. *
  2. * Interactive Matrix Multiply program for the Motorola 68000
  3.  
  4.     ORG    $1000
  5.  
  6. DUART    EQU    $effc01
  7. MR1A    EQU    0
  8. MR2A    EQU    0
  9. SRA    EQU    2
  10. CRA    EQU    4
  11. CSRA    EQU    2
  12. TBA    EQU    6
  13. RBA    EQU    6
  14. IMR    EQU    10
  15. TBB    EQU    $16
  16. CRB    EQU    $14
  17. MR1B    EQU    $10
  18. MR2B    EQU    $10
  19. SRB    EQU    $12
  20.  
  21.     LEA    DUART,A1
  22.     MOVE.B    #%00010000,CRA(A1)     Reset MR?A pointer
  23.     MOVE.B  #%00100011,MR1A(A1)    8 data bits
  24.     MOVE.B  #%00010111,MR2A(A1)    Normal Mode
  25.     MOVE.B  #%10111011,CSRA(A1)    Set clock to 9600
  26.     MOVE.B  #%00000101,CRA(A1)     Enable Rx and Tx
  27.  
  28.     MOVE.L    #$4000,A7              Setup the stack pointer
  29.  
  30. MAIN:    JSR CLEAR
  31.     JSR TITLE
  32.  
  33.     JSR CLEAR
  34.  
  35.     JSR GETSIZE
  36.  
  37.     MOVE.W    MA_C,D1
  38.     MOVE.W    MA_R,D0
  39.     MOVE.L    #MA_DAT,A0
  40.     MOVE.L    #MA_TI,A1
  41.     JSR    MATIN
  42.  
  43.     MOVE.W    MB_C,D1
  44.     MOVE.W    MB_R,D0
  45.     MOVE.L    #MB_DAT,A0
  46.     MOVE.L    #MB_TI,A1
  47.     JSR MATIN
  48.  
  49.     MOVE.W    MA_R,D0
  50.     MOVE.W    MA_C,D1
  51.     MOVE.W    MB_R,D2
  52.     MOVE.W    MB_C,D3
  53.     MOVE.L    #MA_DAT,A0
  54.     MOVE.L    #MB_DAT,A1
  55.     MOVE.L    #MC_DAT,A2
  56.     JSR    MATMULT
  57.  
  58.     MOVE.W    MA_R,D0
  59.     MOVE.W    MB_C,D1
  60.     MOVE.L    #MC_DAT,A0
  61.     MOVE.L    #MC_TI,A1
  62.     JSR    MATOUT
  63.  
  64.     JMP    EXIT
  65.     NOP
  66.  
  67. MA_R:    DS.W    1
  68. MA_C:    DS.W    1
  69. MB_R:    DS.W    1
  70. MB_C:    DS.W    1
  71. MA_DAT:    DS.W    100                Matrix A Data
  72. MB_DAT:    DS.W    100                             Matrix B Data
  73. MC_DAT: DS.L    100                Matrix C Data (Result)
  74. MA_TI:    DC.B    'Enter Matrix A',0,0
  75. MB_TI:    DC.B    'Enter Matrix B',0,0
  76. MC_TI:    DC.B    'Resulting Matrix C',0,0
  77.  
  78. *
  79. * Input a string
  80. *
  81.  
  82. INPUT:        MOVEM.L    A0-A6/D0-D7,-(A7)
  83.  
  84.         MOVE.L    A0,A5            Save buffer address
  85.         MOVE.L    A1,A6            Save valid string address
  86.                 MOVE.L    D0,D7            Save Max length
  87.         MOVE.L    #0,D1            Current string length
  88.  
  89. IN_LOOP:    JSR    GETC            Get a character
  90.  
  91.         CMPI.B    #$08,D0            Is it backspace
  92.         BEQ    IN_BS
  93.  
  94.         CMPI.B    #$0D,D0            Is it return
  95.         BEQ    IN_RET
  96.  
  97. * Make sure it's a valid character
  98.         MOVE.L    A6,A0
  99. IN_VL:        CMPI.B    #0,(A0)            End of valid string?
  100.         BEQ    IN_INVALID
  101.  
  102.         CMP.B    (A0)+,D0        Is it a valid char?
  103.         BEQ    IN_VALID
  104.  
  105.         BRA    IN_VL            Loop
  106.  
  107. IN_INVALID:    JSR    BELL            Sound Bell
  108.         JMP    IN_LOOP            Get another character
  109.  
  110. IN_VALID:    CMP.W    D7,D1            Have we reach max lenght?
  111.         BNE    IN_VA2            NO!
  112.  
  113.         JSR    BELL
  114.         JMP    IN_LOOP
  115.  
  116. IN_VA2:        MOVE.B    D0,0(A5,D1)        Save character in buffer
  117.         ADDI.W    #1,D1            Inc Lenght counter
  118.         JSR    PUTC            Output character to screen
  119.  
  120.         JMP    IN_LOOP
  121.  
  122.  
  123. IN_BS:        CMPI.W    #0,D1            Make sure no wrap around
  124.         BNE    IN_BOK
  125.  
  126.         JSR    BELL
  127.         JMP    IN_LOOP
  128.  
  129. IN_BOK:        MOVE.B    #$08,D0            BackSpace on screen
  130.         JSR    PUTC
  131.         MOVE.B    #$20,D0
  132.         JSR    PUTC
  133.         MOVE.B    #$08,D0
  134.         JSR    PUTC
  135.  
  136.         SUBI.W    #1,D1            Dec length counter
  137.         JMP    IN_LOOP
  138.  
  139.  
  140. IN_RET:        MOVE.B    #0,0(A5,D1)        Null Terminate
  141.  
  142.         MOVEM.L    (A7)+,A0-A6/D0-D7    Restore REGS
  143.  
  144.         RTS
  145. *
  146. * Routines for performing Polled I/O At the Console Serial Port
  147. *
  148. * By: Bradford W. Mott
  149. *
  150.  
  151. LINEFEED:    EQU    10        * LineFeed Character value
  152. CARR_RETURN:    EQU    13        * Carrage Return character value
  153.  
  154. *
  155. * The character in D0 is transmitted to the CONSOLE ACIA.
  156. * The newline character <LF> is expanded into <LF>/<CR>.
  157. *
  158.  
  159. PUTC:    BTST    #2,SRA+DUART        * Test Transmit data register empty
  160.     BEQ.S    PUTC            * If not keep polling
  161.     MOVE.B    D0,TBA+DUART        * Transmit the character
  162.     CMP.B    #LINEFEED,D0        * Check for LINEFEED
  163.     BNE    PUTEXT
  164.     MOVE.B    #CARR_RETURN,D0        * Load CR into D0
  165.     BRA    PUTC            * Output CR
  166. PUTEXT:    RTS                * Return to calling procedure
  167.  
  168.  
  169. *
  170. * Get a character from the CONSOLE ACIA and return it in D0
  171. *
  172.  
  173. GETC:    BTST    #0,SRA+DUART        * Test Receive data register full
  174.     BEQ.S    GETC            * If not keep polling
  175.     MOVE.B    RBA+DUART,D0        * Read the character
  176.     RTS
  177.  
  178. PRINT:        MOVE.L        D0,-(A7)    *SAVE CURRENT REGS TO STACK
  179. PRLOOP:        MOVE.B        (A0)+,D0    *GET A CHARACTER
  180.         CMP.B        #$00,D0        *IS IT A NULL CHARACTER?
  181.         BEQ        PRNTEND        *IF SO, THEN YOU'RE DONE
  182.         JSR        PUTC        *IF NOT, THEN SEND CHARACTER TO SCREEN
  183.         BRA        PRLOOP        *LOOP UNTIL DONE
  184. PRNTEND:    MOVE.L        (A7)+,D0    *RESTORE REGS
  185.         RTS
  186.  
  187.  
  188. TITLE:        MOVE.L     #SCREEN,A0    *INITIALIZE SCREEN DATA POINTER
  189. TILP:        JSR    PRINT        *PRINT DATA TO SCREEN
  190.         CMPI.B    #$3D,(A0)    *END OF SCREEN DATA?
  191.         BNE    TILP        *IF NOT THEN KEEP PRINTING DATA
  192. TILP1:        JSR    GETC        *IF FINISHED, GET A KEY SRIKE
  193.         CMPI.B    #$0D,D0        *IS IT THE RETURN KEY?
  194.         BNE    TILP1        *IF NOT THEN TRY AGAIN
  195.         JSR    PRINT        *IF SO, THEN PRINT CLEAR SCREEN CHARACTERS
  196.         RTS            *RETURN TO MAIN
  197.  
  198. SCREEN:        DC.B    $1B,'[2J'    
  199.         DC.B    '****',$08,$08,$08,$08,$1B,'[4h'
  200.         DC.B    '                                                                        ****',$1B,'[4l',$1B,'E'
  201.         DC.B    '**',$08,$08,$1B,'[4h'
  202.         DC.B    '                                                                            **',$1B,'[4l',$1B,'E'
  203.         DC.B    '* *',$08,$08,$08,$1B,'[4h'
  204.         DC.B    '                                                                          * *',$1B,'[4l',$1B,'E'
  205.         DC.B    '*',$08,$1B,'[4h'
  206.         DC.B    '                                                                              *',$1B,'[4l',$1B,'E',$1B,'E'
  207.         DC.B    '                      M   M   A   TTTTT RRRR   III  X   X',$1B,'E'
  208.         DC.B      '                      MM MM  A A    T   R   R   I    X X ',$1B,'E'
  209.         DC.B    '                      M M M A   A   T   R   R   I     X  ',$1B,'E'
  210.         DC.B    '                      M   M AAAAA   T   RRRR    I    X X ',$1B,'E'
  211.         DC.B    '                      M   M A   A   T   R  R    I   X   X',$1B,'E'
  212.         DC.B    '                      M   M A   A   T   R   R  III  X   X',$1B,'E'
  213.         DC.B    $1B,'E'
  214.         DC.B    '                M   M U   U L     TTTTT  III  PPPP  L     Y   Y',$1B,'E'
  215.         DC.B    '                MM MM U   U L       T     I   P   P L     Y   Y',$1B,'E'
  216.         DC.B    '                M M M U   U L       T     I   P   P L      Y Y ',$1B,'E'
  217.         DC.B     '                M   M U   U L       T     I   PPPP  L       Y  ',$1B,'E'
  218.         DC.B     '                M   M U   U L       T     I   P     L       Y  ',$1B,'E'
  219.         DC.B    '                M   M  UUU  LLLLL   T    III  P     LLLLL   Y  ',$1B,'E'
  220.         DC.B    $1B,'E'
  221.         DC.B    '*',$08,$1B,'[4h'
  222.         DC.B    '                                                                              *',$1B,'[4l',$1B,'E'
  223.         DC.B    '* *',$08,$08,$08,$1B,'[4h'
  224.         DC.B    '                                                                          * *',$1B,'[4l',$1B,'E'
  225.         DC.B    '**',$08,$08,$1B,'[4h'
  226.         DC.B    '                                                                            **',$1B,'[4l',$1B,'E'
  227.         DC.B    '****',$08,$08,$08,$08,$1B,'[4h'
  228.         DC.B    '                                                                        ****',$1B,'[4l',$1B,'E'
  229.         DC.B    'Press RETURN to Continue... ',$1B,'[4l',$00,$3D,$1B,'[2J',$00,$00
  230.                                                                                 
  231. LTOA:        MOVEM.L        D0-D7/A0-A6,-(A7)
  232.  
  233.         MOVE.B        #$00,-(A0)    *APPEND NULL CHARACTER TO OUTPUT STRING
  234.         MOVE.B        #$00,D2        *SET NEGATIVE FLAG TO INDICATE NON NEGATIVE NUMBER FOR NOW
  235.         MOVE.L        D1,D3        *MOVE HEX OUTPUT (D1) TO HOLDER (D3)
  236.         BPL        LTOALOOP    *IF POSITIVE THEN GO CONVERT
  237.         BNE         LTOA2        *IF ZERO THEN YOUR FINISHED
  238.  
  239.         MOVE.B        #48,-(A0)
  240.         BRA        LTOAEND
  241.  
  242. LTOA2:        NEG.L        D3        *IF NEGATIVE THEN NEGATE
  243.         MOVE.B        #$AA,D7        *SET NEGATIVE FLAG
  244.  
  245. LTOALOOP:    JSR        LDIV        *GO PERFORM LONG DIV BY 10 ON HEX NUMBER
  246.         ADD.W        #$30,D3        *ADD $30 TO REMAINDER
  247.         MOVE.B        D3,-(A0)    *MOVE LSB TO ASCII CHAR STRING POINTER
  248.         MOVE.L        D0,D3        *MOVE RECEIVED QUOTIENT TO D3 TO SEND TO LDIV AGAIN
  249.         TST.L        D0        *IS QUOTIENT EQUAL TO ZERO?
  250.         BNE        LTOALOOP    *IF NOT THEN KEEP CONVERTING
  251.  
  252.         CMPI.B        #$AA,D7        *WAS NEGATIVE FLAG SET?
  253.         BNE        LTOAEND        *NO, GO TO THE END
  254.         MOVE.B        #$2D,-(A0)    *YES, APPEND A NEGATIVE SIGN TO ASCII STRING
  255.  
  256.  
  257. LTOAEND:    MOVEM.L        (A7)+,D0-D7/A0-A6
  258.         RTS                *RETURN
  259.  
  260.  
  261. ATOL:        MOVEM.L        D1-D7/A0-A6,-(A7)    *SAVE PERTINENT REGISTERS
  262.         MOVE.B        #0,D4        *SET NEGATIVE FLAG TO OFF
  263.         MOVE.L        #0,D0        *CLEAR RESULT REGISTER
  264.         MOVE.L        #0,D1        *CLEAR CHARACTER HOLDER
  265.  
  266. ATOLLP1:    MOVE.B        (A0)+,D1    *GET FIRST CHARACTER IN ASCII STRING
  267.         BEQ        ATOLDONE    *IF NULL, THEN YOU'RE FINISHED
  268.         MOVE.L        #VALIDSTR,A1    *SET CHARACTER CHECK POINTER
  269.  
  270. ATOLLP2:    CMP.B        #0,(A1)        *CHECKED FOR ALL VALID CHARACTERS?
  271.         BEQ        ATOLLP1        *IF YES, GET NEXT CHARACTER IN ASCII STRING
  272.         CMP.B        #$2D,D1        *IS IT THE NEGATIVE SIGN?
  273.         BEQ        SETNEG        *IF YES, GO SET NEGATIVE FLAG
  274.         CMP.B        (A1)+,D1    *IS THE CHARACTER VALID?
  275.         BNE        ATOLLP2        *IF NOT, COMPARE TO OTHER VALID CHARACTERS
  276.         
  277.         AND.B        #$0F,D1        *MASK UPPER BITS OF ASCII CHARACTER
  278.         MULU        #10,D0        *BEGIN CONVERSION TO BASE 10
  279.         ADD.L        D1,D0        *ADD NEXT DIGIT IN STRING TO RESULT
  280.         BRA        ATOLLP1        *GET NEXT CHARACTER IN ASCII STRING
  281.  
  282. SETNEG:        MOVE.B        #$FF,D4        *SET NEGATIVE FLAG
  283.         BRA        ATOLLP1        *GET NEXT CHARACTER IN ASCII STRING
  284.  
  285. ATOLDONE:    CMP.B        #$FF,D4        *WAS IT A NEGATIVE NUMBER?
  286.         BNE        ATOLEND        *NO, SKIP TO END
  287.         NEG.L        D0        *YES, NEGATE THE RESULT
  288.  
  289. ATOLEND:    MOVEM.L        (A7)+,D1-D7/A0-A6    *RECALL PERTINENT REGISTERS
  290.         RTS                *RETURN RESULT
  291.  
  292. VALIDSTR:    DC.B        '1234567890',0,0
  293.  
  294. LDIV:        MOVE.L        D3,D0        *STORE IN D0 FOR NOW
  295.         CLR.W        D3        *CLEAR LOWER WORD OF DIVIDEND
  296.         SWAP        D3        *MOVE UPPER WORD TO LOWER POSITION
  297.         SWAP        D0        *SWAP THE HOLDER
  298.         DIVU        #$A,D3        *PERFORM CONVERSION DIVISION
  299.         MOVE.W        D3,D0        *MOVE MSW QUOTIENT TO D0
  300.         SWAP        D0        *SWAP IT INTO MSW POSITION
  301.         MOVE.W        D0,D3        *MOVE LSW INTO DIVIDEND
  302.         DIVU        #$A,D3        *PERFORM CONVERSION DIVISION
  303.         MOVE.W        D3,D0        *MOVE LSW QUOTIENT TO D0
  304.         CLR.W        D3        *CLEARS LSW QUOTIENT FROM D3
  305.         SWAP         D3        *SWAPS TOTAL REMAINDER TO LSW OF D3
  306.         RTS                *RETURNS BIG QUOTIENT (D0), REMAINDER (D3)*
  307. * Routines to control the Terminal Display
  308. *
  309. * By: Bradford W. Mott
  310. *
  311.  
  312.  
  313. BELL_CODE:    EQU    07
  314.  
  315.  
  316. *
  317. * This routine sounds the terminal bell
  318. *
  319.  
  320. BELL:    MOVE.L    D0,-(A7)        * Save D0 on stack
  321.     MOVE.L    #BELL_CODE,D0        * Get the BELL character
  322.     JSR    PUTC            * Transmit it to the TERMINAL
  323.     MOVE.L    (A7)+,D0        * Restore D0
  324.     RTS                * Return to calling procedure
  325.  
  326.  
  327. *
  328. * This routine clears the terminal display and homes the cursor
  329. *
  330.  
  331. CLEAR:    MOVEM.L    D0/A0,-(A7)        * Save A0&D0 on stack
  332.     MOVE.L    #CLRSTR,A0        * Load address of clear screen string
  333. CLLOOP:    MOVE.B    (A0)+,D0        * Get a character
  334.     BEQ    CLEXT            * EXIT on NULL
  335.     JSR    PUTC            * Put character to display
  336.     BRA    CLLOOP            * Loop
  337. CLEXT:    MOVEM.L    (A7)+,D0/A0        * Restore A0&D0
  338.     RTS                * Return to calling procedure
  339.  
  340. CLRSTR:    DC.B 27,'[;H',27,'[2J',0,0    * Clear Screen code for VT100
  341.  
  342.  
  343.  
  344. *
  345. * This routine moves the display's cursor to the X/Y coordinates
  346. * specified in the D0 & D1 registers (X=D0,Y=D1)
  347. *
  348.  
  349. POSITION:    MOVEM.L    D0-D7/A0-A6,-(A7)    * Save D0-D1 & A0 on stack
  350.  
  351.         ANDI.L    #255,D0        * Clear the unused parts of 
  352.         ANDI.L    #255,D1        * data register
  353.  
  354.         MOVE.L  #POSSTR+2,A0    * Address of row substring
  355.         DIVU    #10,D1        * Let's convert row number to ASCII
  356.         ADDI.B    #48,D1
  357.         MOVE.B    D1,(A0)+    * Put in POSSTR
  358.         SWAP    D1
  359.         ADDI.B    #48,D1
  360.         MOVE.B    D1,(A0)        * Put in POSSTR
  361.  
  362.         MOVE.B    #48,POSSTR+5
  363.         CMPI.W    #100,D0
  364.         BLT    POS2
  365.  
  366.         SUBI.W    #100,D0
  367.         MOVE.B  #49,POSSTR+5
  368.  
  369. POS2:        MOVE.L    #POSSTR+6,A0    * Address of col substring
  370.         DIVU    #10,D0        * Let's convert column number to ASCII
  371.         ADDI.B    #48,D0
  372.         MOVE.B    D0,(A0)+    * Put in POSSTR
  373.         SWAP    D0
  374.         ADDI.B    #48,D0
  375.         MOVE.B    D0,(A0)        * Put in POSSTR
  376.  
  377.         MOVE.L    #POSSTR,A0    * Get addr of POSITION string
  378. POSLOOP:    MOVE.B    (A0)+,D0    * Get a character
  379.         BEQ    POSEXT        * Exit on NULL
  380.         JSR     PUTC        * Send to the terminal
  381.         BRA    POSLOOP        * Loop
  382.     
  383. POSEXT:        MOVEM.L    (A7)+,D0-D7/A0-A6    * Restore registers
  384.         RTS            * Return to calling procedure
  385.  
  386.         DC.W    0,0,0,0
  387. POSSTR:     DC.B 27,'[00;000;H',0        * Position Cursor code for VT100
  388.         DC.W    0,0,0,0
  389.  
  390.  
  391.  
  392.  
  393.  
  394. *
  395. * This routine gets the sizes of the two matrices to multiply
  396. *
  397.  
  398. GETSIZE:    MOVEM.L    D0-D7/A0-A6,-(SP)
  399.  
  400.         JSR CLEAR
  401.  
  402.         MOVE.L    #GS_TIT,A0        Print title
  403.         JSR    PRINT
  404.  
  405.  
  406. GS_GAC:        MOVE.L    #GS_CA,A0
  407.         JSR    PRINT
  408.  
  409.         MOVE.L    #GS_VALID,A1        Get number of columns
  410.         MOVE.L    #GS_BUFFER,A0
  411.         MOVE.W    #2,D0
  412.         JSR    INPUT
  413.  
  414.         MOVE.L    #GS_BUFFER,A0
  415.         JSR    ATOL
  416.         MOVE.W    D0,MA_C
  417.  
  418.         CMPI.W    #10,D0
  419.         BGT    GS_ACA
  420.         CMPI.W    #1,D0
  421.         BLT    GS_ACA
  422.         BRA    GS_GAR
  423.  
  424. GS_ACA:        MOVE.L    #GS_ERROR,A0
  425.         JSR    PRINT
  426.         JMP    GS_GAC
  427.  
  428.  
  429.  
  430. GS_GAR:        MOVE.L    #GS_RA,A0
  431.         JSR    PRINT
  432.  
  433.         MOVE.L    #GS_VALID,A1        Get number of columns
  434.         MOVE.L    #GS_BUFFER,A0
  435.         MOVE.W    #2,D0
  436.         JSR    INPUT
  437.  
  438.         MOVE.L    #GS_BUFFER,A0
  439.         JSR    ATOL
  440.         MOVE.W    D0,MA_R
  441.  
  442.         CMPI.W    #10,D0
  443.         BGT    GS_ARA
  444.         CMPI.W    #1,D0
  445.         BLT    GS_ARA
  446.         BRA    GS_GBC
  447.  
  448. GS_ARA:        MOVE.L    #GS_ERROR,A0
  449.         JSR    PRINT
  450.         JMP    GS_GAR
  451.  
  452.  
  453.  
  454. GS_GBC:        MOVE.L    #GS_CB,A0
  455.         JSR     PRINT
  456.  
  457.         MOVE.L    #GS_VALID,A1        Get number of columns
  458.         MOVE.L    #GS_BUFFER,A0
  459.         MOVE.W    #2,D0
  460.         JSR    INPUT
  461.  
  462.         MOVE.L    #GS_BUFFER,A0
  463.         JSR    ATOL
  464.         MOVE.W    D0,MB_C
  465.  
  466.         CMPI.W    #10,D0
  467.         BGT    GS_BCA
  468.         CMPI.W    #1,D0
  469.         BLT    GS_BCA
  470.         BRA    GS_GBR
  471.  
  472. GS_BCA:        MOVE.L    #GS_ERROR,A0
  473.         JSR    PRINT
  474.         JMP    GS_GBC
  475.  
  476.  
  477.  
  478. GS_GBR:        MOVE.L    #GS_RB,A0
  479.         JSR     PRINT
  480.  
  481.         MOVE.L    #GS_VALID,A1        Get number of columns
  482.         MOVE.L    #GS_BUFFER,A0
  483.         MOVE.W    #2,D0
  484.         JSR    INPUT
  485.  
  486.         MOVE.L    #GS_BUFFER,A0
  487.         JSR    ATOL
  488.         MOVE.W    D0,MB_R
  489.  
  490.         CMPI.W    #10,D0
  491.         BGT    GS_BRA
  492.         CMPI.W    #1,D0
  493.         BLT    GS_BRA
  494.         BRA    GS_TEST
  495.  
  496. GS_BRA:        MOVE.L    #GS_ERROR,A0
  497.         JSR    PRINT
  498.         JMP    GS_GBR
  499.  
  500.  
  501. GS_TEST:    MOVE.W    MA_C,D0
  502.         CMP.W    MB_R,D0
  503.         BEQ    GS_OK
  504.  
  505.         MOVE.L    #GS_BERR,A0
  506.         JSR    PRINT
  507.         JMP    GS_GAC
  508.  
  509. GS_OK:        MOVEM.L    (A7)+,D0-D7/A0-A6
  510.         RTS
  511.  
  512.  
  513. GS_TIT:        DC.B    ' Matrix Multiply ',10
  514.         DC.B    '-----------------',10,10
  515.         DC.B    'Please enter the sizes of the matrices to multiply.',10,10,0,0
  516.  
  517. GS_CA:        DC.B    10,'Columns in matrix A : ',0
  518. GS_RA:        DC.B    10,'Rows in matrix A    : ',0
  519. GS_CB:        DC.B    10,10,'Columns in matrix B : ',0,0
  520. GS_RB:        DC.B    10,'Rows in matrix B    : ',0
  521.  
  522. GS_VALID:    DC.B    '0123456789',0,0
  523. GS_BUFFER:    DC.B    0,0,0,0,0,0
  524.  
  525. GS_ERROR:    DC.B    10,'Invalid size!!!',10,0    
  526. GS_BERR:    DC.B    10,'Matrix sizes incompatible!!!!!',10,0,0
  527. *
  528. * This routine multiplies two matrices and stores the resulting
  529. * matrix. ( C=AB )
  530. *
  531. * A0 = Matrix A
  532. * A1 = Matrix B
  533. * A2 = Matrix C
  534. *
  535. * D0 = Matrix A number of rows (i)
  536. * D1 = Matrix A number of columns
  537. * D2 = Matrix B number of rows
  538. * D3 = Matrix B number of columns (j)
  539. *
  540.  
  541. MATMULT:
  542.     MOVEM.L    D0-D7/A0-A6,-(A7)
  543.  
  544.     MOVE.W    D3,B_COLS        Save Columns in C
  545.  
  546. I_LOOP:    MOVE.W    B_COLS,D3
  547.     SUBI.W    #1,D0
  548.     BMI    MATFIN
  549.  
  550. J_LOOP:    MOVE.L    #0,SUM
  551.     MOVE.W    D1,D4        T Counter
  552.     SUBI.W    #1,D4
  553.  
  554.     SUB.W    #1,D3
  555.     BMI    I_LOOP
  556.  
  557. T_LOOP:    MOVE.W    D1,D5        Num Columns in A
  558.     MULU    D0,D5        I * Columns in A
  559.     ADD.W    D4,D5        + T
  560.     MULU    #2,D5        Words
  561.     MOVEQ    #0,D6
  562.     MOVE.W    (A0,D5),D6    Get A(i,t)
  563.  
  564.     MOVE.W    B_COLS,D5        Num Columns in B
  565.     MULU    D4,D5        T * Columns in B
  566.     ADD.W    D3,D5        + J
  567.     MULU    #2,D5
  568.     MOVEQ    #0,D7
  569.     MOVE.W    (A1,D5),D7    Get B(t,j)
  570.  
  571.     MULS    D6,D7        A(i,t)*B(t,j)
  572.     ADD.L    D7,SUM        add to running Sum
  573.  
  574.     SUBI.W    #1,D4
  575.     BPL    T_LOOP
  576.  
  577.     MOVE.W    B_COLS,D5    Num Columns in C
  578.     MULU    D0,D5        I * Num Columns in C
  579.     ADD.W    D3,D5        + J
  580.     MULU    #4,D5
  581.     MOVE.L    SUM,(A2,D5)    Store C(i,j)
  582.  
  583.     BRA    J_LOOP
  584.     BRA    I_LOOP
  585.  
  586. MATFIN:    MOVEM.L    (A7)+,D0-D7/A0-A6
  587.     RTS
  588.  
  589.  
  590. SUM:    DC.L    $1
  591. B_COLS:    DC.W    $1
  592. *
  593. *     MATOUT
  594. **
  595. * D0 contains the number of columns
  596. * D1 contains the number of rows
  597. *
  598. * A0 contains a pointer to a buffer to store matrix elements in
  599. * A1 contains a pointer to the a title string
  600. *
  601. * By: Bradford W. Mott
  602. *
  603.  
  604.  
  605. MATOUT:        MOVEM.L    A0-A6/D0-D7,-(A7)    Save registers on stack
  606.  
  607.         MOVE.L    A0,MO_DATA        Store buffer address
  608.         MOVE.W    D0,MO_ROW        Store num of rows
  609.         MOVE.W    D1,MO_COL        Store num of columns
  610.  
  611.  
  612.         JSR    CLEAR            Clear the display
  613.  
  614.         MOVE.L    #MO_32ON,A0        Turn 132 mode on
  615.         JSR    PRINT
  616.  
  617.         MOVE.W    #57,D0            X position of cursor
  618.         MOVE.W    #2,D1            Y position of cursor
  619.         JSR    POSITION        Position the Cursor
  620.  
  621.         MOVE.L    A1,A0            Print the Title String
  622.         JSR    PRINT
  623.  
  624.  
  625.         MOVE.L    #MO_Y,A0        Pointer to Y position array
  626.         MOVEQ    #0,D0            Clear LCV (Loop Control Var)
  627.  
  628. MO_L1:        MOVE.W    #20,D1            Calculate Y position
  629.         SUB.W    MO_ROW,D1
  630.         DIVU    #2,D1
  631.         ADD.W    D0,D1            (20-row)/2+counter
  632.         MOVE.B    D1,0(A0,D0)        Store in array
  633.  
  634.         ADDQ.W    #1,D0
  635.         CMP.W    MO_ROW,D0
  636.         BNE    MO_L1
  637.  
  638.  
  639.         MOVE.L    #MO_X,A0        Pointer to X position array
  640.         MOVEQ    #0,D0            Clear LCV (Loop Control Var)
  641.  
  642. MO_L2:        MOVE.W    #132,D1            Calculate X position
  643.         MOVE.W  MO_COL,D2
  644.         MULU    #10,D2
  645.         SUB.W    D2,D1
  646.         DIVU    #2,D1
  647.         MOVE.W    D0,D2
  648.         MULU    #10,D2
  649.         ADD.W    D2,D1            (132-col*10)/2+counter*10
  650.         MOVE.B    D1,0(A0,D0)        Store in array
  651.  
  652.         ADDQ.W    #1,D0
  653.         CMP.W    MO_COL,D0
  654.         BNE    MO_L2
  655.  
  656.  
  657. * Draw the Matrix outline
  658.  
  659.         MOVE.L    #MO_Y,A0        Pointer to Y position array
  660.         MOVEQ    #0,D7            Clear LCV (Loop Control Var)
  661.  
  662. MO_L3:        MOVE.W    #132,D0            Calculate X position
  663.         MOVE.W    MO_COL,D1
  664.         MULU    #10,D1
  665.         SUB.W    D1,D0
  666.         DIVU    #2,D0
  667.         SUBI.W    #2,D0            D0=(132-col*10)/2-2
  668.  
  669.         MOVE.B    0(A0,D7),D1        Get Y Position
  670.  
  671.         JSR    POSITION        Position Cursor
  672.         MOVE.B    #$7C,D0            the "|" character
  673.         JSR    PUTC
  674.  
  675.  
  676.         MOVE.W    #132,D0            Calculate X position
  677.         MOVE.W    MO_COL,D1
  678.         MULU    #10,D1
  679.         SUB.W    D1,D0
  680.         DIVU    #2,D0
  681.         ADD.W    D1,D0            D0=(132-col*10)/2+col*10
  682.  
  683.         MOVE.B    0(A0,D7),D1        Get Y Position
  684.  
  685.         JSR    POSITION        Position Cursor
  686.         MOVE.B    #$7C,D0            the "|" character
  687.         JSR    PUTC
  688.  
  689.         ADDQ.W    #1,D7
  690.         CMP.W    MO_ROW,D7
  691.         BNE    MO_L3
  692.  
  693. * Get the data for each element.
  694.  
  695.         MOVEQ    #0,D7            LCV for row
  696.         MOVE.L    #MO_X,A3
  697.         MOVE.L    #MO_Y,A4
  698.  
  699. MO_L4:        MOVEQ    #0,D6            LCV for column
  700.  
  701. MO_L5:        MOVE.B    0(A3,D6),D0
  702.         MOVE.B    0(A4,D7),D1
  703.         JSR    POSITION
  704.  
  705.  
  706.         MOVE.L    #$20202020,MO_OUT      Set output to all spaces
  707.         MOVE.L    #$20202020,MO_OUT+4
  708.         MOVE.L    #$20200000,MO_OUT+8
  709.  
  710.         MOVE.L    MO_DATA,A0
  711.         MOVE.W    MO_COL,D0
  712.         MULU    D7,D0            D0=row*col
  713.         MULU    #4,D0            *4
  714.  
  715.         MOVE.W    D6,D1
  716.         MULU    #4,D1
  717.         ADD.W    D1,D0
  718.  
  719.         MOVE.L    0(A0,D0),D1        Store entry in Matrix Buffer
  720.  
  721.         MOVE.L    #MO_OUT+10,A0
  722.         JSR    LTOA
  723.  
  724.         MOVE.L    #MO_OUT,A0
  725.         JSR    PRINT
  726.  
  727.         ADDQ.W    #1,D6
  728.         CMP.W    MO_COL,D6
  729.         BNE    MO_L5
  730.  
  731.         ADDQ.W    #1,D7
  732.         CMP.W    MO_ROW,D7
  733.         BNE    MO_L4
  734.  
  735.  
  736. * PRINT PROMPT
  737.         MOVE.W    #0,D0
  738.         MOVE.W    #22,D1
  739.         JSR    POSITION
  740.         MOVE.L    #MO_PROMPT,A0
  741.         JSR    PRINT
  742.  
  743. MO_LKEY:    JSR    GETC
  744.         CMPI.B    #13,D0
  745.         BNE    MO_LKEY    
  746.  
  747. * Go back to 80 column mode
  748.         MOVE.L    #MO_32OFF,A0
  749.         JSR    PRINT
  750.  
  751. * Return to calling routine
  752.  
  753.         MOVEM.L    (A7)+,A0-A6/D0-D7    Restore Registers
  754.  
  755.         RTS                Return to caller
  756.  
  757.  
  758. MO_OUT:         DC.B    '-1000',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  759. MO_PROMPT:      DC.B    'Press Return Key...',0
  760. MO_HOFF:        DC.B    27,'[0m',0,0
  761. MO_SSR:         DC.B    27,'[20;23r',0,0
  762. MO_SRR:         DC.B    27,'[0;24r',0
  763. MO_Y:           DC.B    0,0,0,0,0,0,0,0,0,0,0,0
  764. MO_X:           DC.B    0,0,0,0,0,0,0,0,0,0,0,0
  765. MO_DATA:        DC.L    0
  766. MO_ROW:         DC.W    0
  767. MO_COL:         DC.W    0
  768. MO_32ON:    DC.B    27,'[?3h',0
  769. MO_32OFF:    DC.B    27,'[?3l',0
  770.  
  771.  
  772. *
  773. *     MATIN
  774. *
  775. * This routine allows the user to enter the elements of a matrix
  776. *
  777. * D0 contains the number of columns
  778. * D1 contains the number of rows
  779. *
  780. * A0 contains a pointer to a buffer to store matrix elements in
  781. * A1 contains a pointer to the a title string
  782. *
  783. * By: Bradford W. Mott
  784. *
  785.  
  786.  
  787. MATIN:        MOVEM.L    A0-A6/D0-D7,-(A7)    Save registers on stack
  788.  
  789.         MOVE.L    A0,MI_DATA        Store buffer address
  790.         MOVE.W    D0,MI_ROW        Store num of rows
  791.         MOVE.W    D1,MI_COL        Store num of columns
  792.  
  793.         JSR    CLEAR            Clear the display
  794.  
  795.         MOVE.W    #33,D0            X position of cursor
  796.         MOVE.W    #2,D1            Y position of cursor
  797.         JSR    POSITION        Position the Cursor
  798.  
  799.         MOVE.L    A1,A0            Print the Title String
  800.         JSR    PRINT
  801.  
  802.  
  803.         MOVE.L    #MI_Y,A0        Pointer to Y position array
  804.         MOVEQ    #0,D0            Clear LCV (Loop Control Var)
  805.  
  806. MI_L1:        MOVE.W    #20,D1            Calculate Y position
  807.         SUB.W    MI_ROW,D1
  808.         DIVU    #2,D1
  809.         ADD.W    D0,D1            (20-row)/2+counter
  810.         MOVE.B    D1,0(A0,D0)        Store in array
  811.  
  812.         ADDQ.W    #1,D0
  813.         CMP.W    MI_ROW,D0
  814.         BNE    MI_L1
  815.  
  816.  
  817.         MOVE.L    #MI_X,A0        Pointer to X position array
  818.         MOVEQ    #0,D0            Clear LCV (Loop Control Var)
  819.  
  820. MI_L2:        MOVE.W    #80,D1            Calculate X position
  821.         MOVE.W  MI_COL,D2
  822.         MULU    #6,D2
  823.         SUB.W    D2,D1
  824.         DIVU    #2,D1
  825.         MOVE.W    D0,D2
  826.         MULU    #6,D2
  827.         ADD.W    D2,D1            (80-col*6)/2+counter*6
  828.         MOVE.B    D1,0(A0,D0)        Store in array
  829.  
  830.         ADDQ.W    #1,D0
  831.         CMP.W    MI_COL,D0
  832.         BNE    MI_L2
  833.  
  834.  
  835. * Draw the Matrix outline
  836.  
  837.         MOVE.L    #MI_Y,A0        Pointer to Y position array
  838.         MOVEQ    #0,D7            Clear LCV (Loop Control Var)
  839.  
  840. MI_L3:        MOVE.W    #80,D0            Calculate X position
  841.         MOVE.W    MI_COL,D1
  842.         MULU    #6,D1
  843.         SUB.W    D1,D0
  844.         DIVU    #2,D0
  845.         SUBI.W    #2,D0            D0=(80-col*6)/2-2
  846.  
  847.         MOVE.B    0(A0,D7),D1        Get Y Position
  848.  
  849.         JSR    POSITION        Position Cursor
  850.         MOVE.B    #$7C,D0            the "|" character
  851.         JSR    PUTC
  852.  
  853.  
  854.         MOVE.W    #80,D0            Calculate X position
  855.         MOVE.W    MI_COL,D1
  856.         MULU    #6,D1
  857.         SUB.W    D1,D0
  858.         DIVU    #2,D0
  859.         ADD.W    D1,D0            D0=(80-col*6)/2+col*6
  860.  
  861.         MOVE.B    0(A0,D7),D1        Get Y Position
  862.  
  863.         JSR    POSITION        Position Cursor
  864.         MOVE.B    #$7C,D0            the "|" character
  865.         JSR    PUTC
  866.  
  867.         ADDQ.W    #1,D7
  868.         CMP.W    MI_ROW,D7
  869.         BNE    MI_L3
  870.  
  871.  
  872.  
  873. * Set the Display scrolling region
  874.  
  875.         MOVE.L    #MI_SSR,A0        Addr of string
  876.         JSR    PRINT
  877.  
  878.  
  879. * Get the data for each element.
  880.  
  881.         MOVEQ    #0,D7            LCV for row
  882.         MOVE.L    #MI_X,A3
  883.         MOVE.L    #MI_Y,A4
  884.  
  885. MI_L4:        MOVEQ    #0,D6            LCV for column
  886.  
  887. MI_L5:        MOVE.B    0(A3,D6),D0
  888.         MOVE.B    0(A4,D7),D1
  889.         JSR    POSITION
  890.  
  891.         MOVE.L    #MI_HON,A0        Turn Highlight on
  892.         JSR    PRINT
  893.  
  894.         MOVE.L    #MI_SPACE,A0        Print Space
  895.         JSR    PRINT
  896.  
  897.         MOVE.L    #MI_HOFF,A0        Turn Highlight off
  898.         JSR    PRINT
  899.  
  900.         MOVE.W    #0,D0
  901.         MOVE.W    #23,D1
  902.         JSR    POSITION
  903.  
  904. MI_AGAIN:    MOVE.L    #MI_PROMPT,A0        Print prompt
  905.         JSR    PRINT
  906.  
  907.         MOVE.L    #MI_INPUT,A0
  908.         MOVE.L    #MI_VALID,A1
  909.         MOVE.L    #5,D0
  910.         JSR    INPUT            INPUT the number
  911.  
  912.         MOVE.L    #10,D0            NEWLINE
  913.         JSR    PUTC
  914.  
  915.         MOVE.L    #MI_INPUT,A0
  916.         JSR    ATOL            Convert ASCII to Long INT
  917.         MOVE.L    D0,MI_INN
  918.  
  919.         CMPI.W    #1000,D0        Make sure number is right
  920.         BGT    MI_ER            size
  921.         CMPI.W    #-1000,D0
  922.         BLT    MI_ER
  923.         
  924.         BRA    MI_NER
  925.  
  926. MI_ER:        MOVE.L    #MI_ERROR,A0        Print Error Message
  927.         JSR    PRINT
  928.         JMP    MI_AGAIN        Try Again!!!
  929.  
  930. MI_NER:        MOVE.L    #$20202020,MI_OUT      Set output to all spaces
  931.         MOVE.L    #$20000000,MI_OUT+4
  932.         MOVE.L    #MI_OUT+6,A0
  933.         MOVEQ    #0,D1
  934.         MOVE.L    MI_INN,D1
  935.         JSR    LTOA
  936.  
  937.                MOVE.B 0(A3,D6),D0
  938.         MOVE.B 0(A4,D7),D1
  939.         JSR    POSITION
  940.  
  941.         MOVE.L    #MI_OUT,A0        Print Entry
  942.         JSR    PRINT
  943.  
  944.         MOVE.L    MI_DATA,A0
  945.         MOVE.W    MI_COL,D0
  946.         MULU    D7,D0            D0=row*col
  947.         MULU    #2,D0            *2
  948.  
  949.         MOVE.W    D6,D1
  950.         MULU    #2,D1
  951.         ADD.W    D1,D0
  952.  
  953.         MOVE.L    MI_INN+2,0(A0,D0)        Store entry in Matrix Buffer
  954.  
  955.         ADDQ.W    #1,D6
  956.         CMP.W    MI_COL,D6
  957.         BNE    MI_L5
  958.  
  959.         ADDQ.W    #1,D7
  960.         CMP.W    MI_ROW,D7
  961.         BNE    MI_L4
  962.  
  963. * Reset the terminal's scrolling region
  964.  
  965.         MOVE.L    #MI_SRR,A0
  966.         JSR    PRINT
  967.  
  968.  
  969. * Return to calling routine
  970.  
  971.         MOVEM.L    (A7)+,A0-A6/D0-D7    Restore Registers
  972.  
  973.         RTS                Return to caller
  974.  
  975.  
  976. MI_INN:         DC.L   0,0,0,0,0
  977. MI_OUT:         DC.B    '-1000',0,0,0,0,0,0,0,0,0
  978. MI_VALID:       DC.B    '0123456789-',0
  979. MI_INPUT:       DC.B    0,0,0,0,0,0,0,0,0,0,0,0,0,0
  980. MI_PROMPT:      DC.B    'Enter Element: ',0
  981. MI_ERROR:       DC.B    '*** Problem with entry!!!!',10,10,0,0
  982. MI_SPACE:       DC.B    '     ',0,0
  983. MI_HON:         DC.B    27,'[5;7m',0,0
  984. MI_HOFF:        DC.B    27,'[0m',0,0
  985. MI_SSR:         DC.B    27,'[20;23r',0,0
  986. MI_SRR:         DC.B    27,'[0;24r',0
  987. MI_Y:           DC.B    0,0,0,0,0,0,0,0,0,0,0,0
  988. MI_X:           DC.B    0,0,0,0,0,0,0,0,0,0,0,0
  989. MI_DATA:        DC.L    0
  990. MI_ROW:         DC.W    0
  991. MI_COL:         DC.W    0
  992.  
  993.  
  994. EXIT:        MOVE.L        #QUITMSG,A0    *INITIALIZE QUIT PROMPT
  995.         JSR         PRINT        *PRINT QUIT PROMPT
  996.         JSR        GETC        *GET RESPONSE
  997.         CMP.B        #$59,D0        *A VALID CHARACTER?
  998.         BEQ        QSTRT        *YES, START OVER
  999.         CMP.B        #$79,D0        *A VALID CHARACTER?
  1000.         BEQ        QSTRT        *YES, START OVER
  1001.         CMP.B        #$4E,D0        *A VALID CHARACTER?
  1002.         BEQ        QFIN        *NO, QUIT PROGRAM
  1003.         CMP.B        #$6E,D0        *A VALID CHARACTER?
  1004.         BEQ        QFIN        *NO, QUIT PROGRAM
  1005.         BRA        EXIT        *NOT A VALID CHARACTER
  1006.  
  1007. QSTRT:        BRA        MAIN        *RE-EXECUTE MAIN PROGRAM
  1008.  
  1009. QFIN:        MOVE.L        #ENDMSG,A0    *INITIALIZE FINAL MESSAGE
  1010.         JSR        PRINT        *PRINT FINAL MESSAGE
  1011. NOMOE:        BRA        NOMOE        *INFINITE LOOP
  1012.  
  1013. QUITMSG:    DC.B        10,'Multiply Another Set? <Y,y,N,n>...',0,0
  1014. ENDMSG:        DC.B        10,10,'THANK YOU, GOODBYE..',0
  1015.  
  1016.  
  1017.